﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;

namespace ui
{
    public enum ControlTypes
    {
        Label = 1,
        RadioButton = 2,
        CheckBox = 3,
        ScrollingGraph = 4,
        Image = 5,
        Button = 6,
        ListBox = 7,
        Frame = 8,
        Clock = 9,
        Window = 0
    }

    public abstract class _control
    {
        [Browsable(false)]
        public ControlTypes type;

        int _x;
        int _y;
        int _width;
        int _height;

        [XmlIgnore()]
        public Graphics g;
        [XmlIgnore()]
        public _tpanel pic;

        bool _selected = false;
        string _name = "";

        [XmlIgnore()]
        [Browsable(false)]
        public frmMain parent;

        public enum Direction
        {
            UpperLeft,
            UpperRight,
            LowerLeft,
            LowerRight
        }

        public _control()
        {
        }

        [Category("(Control)"), Description("Name")]
        public string name
        {
            get { return _name; }
            set { _name = value; if(pic!=null)pic.Invalidate(); }
        }

        [Browsable(false)]
        [XmlIgnore()]
        [Category("(Control)"), Description("Selected")]
        public bool selected
        {
            get { return _selected; }
            set { _selected = value; if (pic != null)pic.Invalidate(); }
        }

        [Category("Position"), Description("X Position")]
        public int x
        {
            get { return _x; }
            set { _x = value; if (pic != null) { pic.Left = value; pic.Invalidate(); } }
        }

        [Category("Position"), Description("Y Position")]
        public int y
        {
            get { return _y; }
            set { _y = value; if (pic != null) { pic.Top = value; pic.Invalidate(); } }
        }

        [Category("Position"), Description("Width of Control")]
        public int width
        {
            get { return _width; }
            set { _width = value; if (pic != null) { pic.Width = value; pic.Invalidate(); } }
        }

        [Category("Position"), Description("Height of Control")]
        public int height
        {
            get { return _height; }
            set { _height = value; if (pic != null) { pic.Height = value; pic.Invalidate(); } }
        }

        public virtual void setup(PictureBox p)
        {
            pic = new _tpanel();
            pic.BorderStyle = BorderStyle.None;

            pic.Width = width;
            pic.Height = height;

            p.Controls.Add(pic);
            pic.BringToFront();

            pic.Paint += new PaintEventHandler(render);

            pic.MouseDown += new MouseEventHandler(pic_MouseDown);
            pic.MouseMove += new MouseEventHandler(pic_MouseMove);
            pic.MouseUp += new MouseEventHandler(pic_MouseUp);

            p.Invalidate();
        }

        int ox;
        int oy;
        int ow;
        int oh;
        bool moving = false;
        bool sizing = false;
        public bool sizeable = true;
        Direction dir = new Direction();

        void pic_MouseUp(object sender, MouseEventArgs e)
        {
            moving = false;
            sizing = false;
        }

        void pic_MouseMove(object sender, MouseEventArgs e)
        {
            pic.Cursor = Cursors.Default;

            if (selected && sizeable)
            {
                if (e.X <= 8 && e.Y <= 8) // Upper Left
                {
                    pic.Cursor = Cursors.SizeNWSE;
                }
                else if (e.X >= width - 8 && e.Y <= 8) // Upper Right
                {
                    pic.Cursor = Cursors.SizeNESW;
                }
                else if (e.X <= 8 && e.Y >= height - 8) // Lower Left
                {
                    pic.Cursor = Cursors.SizeNESW;
                }
                else if (e.X >= width - 8 && e.Y >= height - 8) // Lower Right
                {
                    pic.Cursor = Cursors.SizeNWSE;
                }
            }

            if (moving)
            {
                if (e.Button != MouseButtons.Left)
                {
                    moving = false;
                    sizing = false;
                    return;
                }

                int tx = e.X + x - ox;
                int ty = e.Y + y - oy;

                tx -= tx % (int)parent.gridW.Value;
                ty -= ty % (int)parent.gridH.Value;

                int _w = width;
                int _h = height;

                if (sizing && sizeable)
                {
                    int dx;
                    int dy;

                    switch (dir)
                    {
                        case Direction.UpperLeft:
                            dx = x - tx;
                            dy = y - ty;
                            _w = width + dx;
                            _h = height + dy;
                            break;
                        case Direction.UpperRight:
                            dx = tx - x;
                            dy = y - ty;
                            _w = dx + ow;
                            _h = height + dy;
                            tx = x;
                            break;
                        case Direction.LowerLeft:
                            dx = x - tx;
                            dy = ty - y;
                            _w = width + dx;
                            _h = dy + oh;
                            ty = y;
                            break;
                        case Direction.LowerRight:
                            dx = tx - x;
                            dy = ty - y;
                            _w = dx + ow;
                            _h = dy + oh;
                            tx = x;
                            ty = y;
                            break;
                    }
                } 

                width = _w;
                height = _h;
                x = tx;
                y = ty;
            }
        }

        void pic_MouseDown(object sender, MouseEventArgs e)
        {
            moving = true;

            ox = e.X;
            oy = e.Y;
            ow = width;
            oh = height;

            if (e.X <= 8 && e.Y <= 8) // Upper Left
            {
                sizing = true;
                dir = Direction.UpperLeft;
            }
            else if (e.X >= width - 8 && e.Y <= 8) // Upper Right
            {
                sizing = true;
                dir = Direction.UpperRight;
            }
            else if (e.X <= 8 && e.Y >= height - 8) // Lower Left
            {
                sizing = true;
                dir = Direction.LowerLeft;
            }
            else if (e.X >= width - 8 && e.Y >= height - 8) // Lower Right
            {
                sizing = true;
                dir = Direction.LowerRight;
            }
        }

        public virtual void render(object sender, PaintEventArgs e)
        {
            Pen p1 = new Pen(Color.Black);
            Brush b1 = new SolidBrush(Color.FromArgb(200,50,200,60));

            if (selected)
            {
                g.DrawRectangle(new Pen(new HatchBrush(HatchStyle.Cross, Color.FromArgb(150, 50, 200, 60),Color.FromArgb(100, 120, 220, 130)), 6), 0, 0, width, height);
            }

            if (selected && sizeable)
            {
                g.FillPolygon(b1, new Point[] { new Point(0, 0), new Point(0, 8), new Point(8, 0) });
                g.FillPolygon(b1, new Point[] { new Point(width, 0), new Point(width - 8 , 0), new Point(width, 8) });
                g.FillPolygon(b1, new Point[] { new Point(0, height), new Point(0, height -9), new Point(9, height) });
                g.FillPolygon(b1, new Point[] { new Point(width, height), new Point(width -9, height), new Point(width, height -9) });

                g.DrawPolygon(p1, new Point[] { new Point(0, 0), new Point(0, 8), new Point(8, 0) });
                g.DrawPolygon(p1, new Point[] { new Point(width-1, 0), new Point(width - 9, 0), new Point(width-1, 8) });
                g.DrawPolygon(p1, new Point[] { new Point(0, height-1), new Point(0, height - 9), new Point(8, height-1) });
                g.DrawPolygon(p1, new Point[] { new Point(width-1, height-1), new Point(width - 9, height -1), new Point(width -1, height - 9) });
            }
        }
    }
}
